﻿#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
// 支持动态增长的栈
//
typedef int STDataType;
typedef struct Stack
{
	STDataType* _a;
	int _top;		// 栈顶
	int _capacity;  //容量
}Stack;

// 初始化栈   在这里不用开辟空间，初始化就行。开辟空间在入栈的时候进行
void StackInit(Stack* ps)
{
	assert(ps);
	ps->_a = NULL;
	//在这里，_top指向的是栈顶的下一个元素
	ps->_top = 0;
	ps->_capacity = 0;
		
}
// 入栈 
void StackPush(Stack* ps, STDataType data)
{
	assert(ps);
	//30行到42行，完成没有容量的情况下扩容
	if (ps->_top == ps->_capacity)
	{
		int newcapacity = ps->_capacity == 0 ? 4 : ps->_capacity * 2;
		STDataType* tmp = (STDataType*)realloc(ps->_a, newcapacity * sizeof(STDataType));
		//ps->_capacity == 0 ? ((STDataType*)realloc(ps->_a,sizeof(STDataType))): (STDataType*)realloc(ps->_a,ps->_capacity * 2 * (sizeof(STDataType)));
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}
		ps->_a = tmp;
		ps->_capacity = newcapacity;
	}
	//在有容量的情况下，进行栈的入栈操作
	ps->_a[ps->_top] = data;
	ps->_top++;
}
// 出栈 
void StackPop(Stack* ps)
{
	assert(ps);
	//assert(ps->_top > 0);
	ps->_top--;
}
// 获取栈顶元素 
STDataType StackTop(Stack* ps) 
{
	assert(ps);
	assert(ps->_top > 0);
	return ps->_a[ps->_top-1];
}
// 获取栈中有效元素个数 
int StackSize(Stack* ps)
{
	assert(ps);
	return ps->_top;
}
// 检测栈是否为空，如果为空返回非零结果，如果不为空返回0 
int StackEmpty(Stack* ps)
{
	assert(ps);
	return ps->_top == 0;
}

// 销毁栈 
void StackDestroy(Stack* ps)
{
	assert(ps);
	free(ps->_a);
	ps->_a = NULL;
	ps->_top = ps->_capacity = 0;
}

int main()
{
	// 入栈：1 2 3 4
	// 出栈：4 3 2 1  /  2 4 3 1
	Stack s;
	StackInit(&s);
	StackPush(&s, 1);
	StackPush(&s, 2);

	printf("%d ", StackTop(&s));
	StackPop(&s);

	StackPush(&s, 3);
	StackPush(&s, 4);

	while (!StackEmpty(&s))
	{
		printf("%d ", StackTop(&s));
		StackPop(&s);
	}

	StackDestroy(&s);
}

